package edu.uoc.vmerinom.tfc.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;

import edu.uoc.vmerinom.tfc.domain.Componente;
import edu.uoc.vmerinom.tfc.domain.Grupo;
import edu.uoc.vmerinom.tfc.domain.Usuario;
import edu.uoc.vmerinom.tfc.service.ComponentesService;
import edu.uoc.vmerinom.tfc.service.GruposService;
import edu.uoc.vmerinom.tfc.support.Message;

/**
 * Manejador con las acciones relacionadas con la gestión de componentes.
 * 
 * @author Víctor Manuel Merino Martínez
 * 
 */
@Name("componentesAction")
@Scope(ScopeType.CONVERSATION)
public class ComponentesAction {
	/**
	 * Default Serial Version ID.
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * Servicio de componentes.
	 */
	@In(create = true)
	ComponentesService componentesService;

	/**
	 * Servicio de grupos.
	 */
	@In(create = true)
	GruposService gruposService;

	/**
	 * Usuario autenticado.
	 */
	@In(value = "usuario")
	Usuario login;

	/**
	 * Componente seleccionado.
	 */
	Componente componente;

	/**
	 * Listado de componentes.
	 */
	List<Componente> componentes;

	/**
	 * Componentes seleccionados.
	 */
	List<Componente> componentesSeleccionados;

	/**
	 * Lista de grupos.
	 */
	List<Grupo> grupos;

	/**
	 * Lista de usuarios.
	 */
	List<Usuario> usuarios;

	/**
	 * Usuario seleccionado.
	 */
	Usuario usuario;

	/**
	 * Grupo selecionado.
	 */
	Grupo grupo;

	/**
	 * Mapa de componentes seleccionados.
	 */
	Map<Componente, Boolean> selected;

	/**
	 * Indica si ya se ha seleccionado o no un representante.
	 */
	boolean representanteSeleccionado;

	/**
	 * Indica si se muestra o no el panel.
	 */
	boolean showMemberPanel;

	/**
	 * Indica si se muestra el panel de componentes del grupo seleccionado.
	 */
	boolean verComponentes;

	/**
	 * Indica si se muestra el panel para añadir componentes al grupo
	 * seleccionado.
	 */
	boolean asignarComponentes;

	/**
	 * Carga los datos para la pantalla incial.
	 */
	public void load() {
		grupos = componentesService.obtenerGruposActivos();
		grupo = new Grupo();
		selected = new HashMap<Componente, Boolean>();
		componentes = new ArrayList<Componente>();
		componentesSeleccionados = new ArrayList<Componente>();
		verComponentes = false;
		asignarComponentes = false;
	}

	/**
	 * Carga el listado de grupos que mostrará en la pantalla.
	 */
	public void cargarGrupos() {
		grupos = componentesService.obtenerGrupos(usuario.getId());
		componente = new Componente();
		grupo = new Grupo();
		showMemberPanel = true;
	}

	/**
	 * Carga el listado de usuarios que mostrará en la pantalla.
	 */
	public void cargarUsuarios() {
		usuarios = componentesService.obtenerUsuariosActivos(grupo.getId());
		componente = new Componente();
		usuario = new Usuario();
		showMemberPanel = true;
		componentesSeleccionados = new ArrayList<Componente>();
		componentes = new ArrayList<Componente>();
		selected = new HashMap<Componente, Boolean>();
		representanteSeleccionado = false;
		for (Usuario u : usuarios) {
			Componente com = new Componente();
			com.setUsuario(u);
			com.setGrupo(grupo);
			componentes.add(com);
		}
	}

	/**
	 * Muestra la tabla de los componentes del grupo.
	 */
	public void mostrarComponentes() {
		componentesService.actualizarEstadoGrupo(grupo);
		verComponentes = true;
	}

	/**
	 * Muestra la tabla de usuarios
	 */
	public void listarUsuarios() {
		asignarComponentes = true;
		cargarUsuarios();
	}

	/**
	 * Almacena los cambios realizados en base de datos.
	 */
	public void guardar() {
		if (grupo.getComponentes() != null) {
			componentesSeleccionados.addAll(grupo.getComponentes());
		}
		guardarComponentes();
		load();
	}

	/**
	 * Comprueba si existe más de un representante en el grupo.
	 * 
	 * @param c
	 *            Componente seleccionado
	 */
	public void checkRepresentante(Componente c) {
		boolean encontrado = false;
		if (!representanteSeleccionado) {
			if (!componentesSeleccionados.isEmpty()) {
				for (Componente com : componentesSeleccionados) {
					if (!com.equals(c) && com.isRepresentante()) {
						encontrado = true;
					}
				}
			}
			if (!encontrado && grupo.getComponentes() != null && !grupo.getComponentes().isEmpty()) {
				for (Componente com : grupo.getComponentes()) {
					if (com.isRepresentante()) {
						encontrado = true;
					}
				}
			}
			if (encontrado) {
				Message.error("bands.error.members.representative");
				c.setRepresentante(false);
			} else {
				representanteSeleccionado = true;
			}
		} else {
			if (c.isRepresentante()) {
				Message.error("bands.error.members.representative");
				c.setRepresentante(false);
			} else {
				representanteSeleccionado = false;
			}
		}
	}

	/**
	 * Añade o elimina el componente del listado de componentes a insertar.
	 * 
	 * @param c
	 *            Componente a insertar o borrar
	 */
	public void checkMember(Componente c) {
		if (componentesSeleccionados.contains(c)) {
			c.setActividad("");
			c.setRepresentante(false);
			componentesSeleccionados.remove(c);
			selected.put(c, false);
		} else {
			boolean success = true;
			if (c.getAlta() == null) {
				Message.error("bands.error.members.registration.date.null");
				selected.put(c, false);
				success = false;
			} else if (c.getBaja() != null && c.getAlta().compareTo(c.getBaja()) > 0) {
				Message.error("bands.error.members.date.compare");
				selected.put(c, false);
				success = false;
			}
			if ("".equals(c.getActividad())) {
				Message.error("bands.error.members.instrument.null");
				selected.put(c, false);
				success = false;
			}

			if (success) {
				componentesSeleccionados.add(c);
				selected.put(c, true);
			}
		}
	}

	/**
	 * Crea un componente por cada usuario seleccionado. Se le añade la fecha
	 * actual como fecha de alta, no se marca como representante ni se le indica
	 * actividad desempeñada.
	 */
	public void guardarComponentes() {
		if (!componentesSeleccionados.isEmpty()) {
			componentesService.insertarModificarComponentes(componentesSeleccionados);
			if (verComponentes) {
				Message.info("success");
			} else {
				Message.info("bands.info.members.success");
			}
			hideMemberPanel();
		} else {
			Message.error("bands.error.members.empty");
		}
	}

	/**
	 * Guarda los datos del componente.
	 */
	public void guardarComponente() {
		boolean success = true;
		if (componente.getAlta() == null) {
			Message.error("users.error.member.registration.date.null");
			success = false;
		} else if (componente.getBaja() != null && componente.getBaja().compareTo(componente.getAlta()) < 0) {
			Message.error("users.error.member.compare.dates");
			success = false;
		}
		if (grupo == null) {
			Message.error("users.error.member.band.null");
			success = false;
		} else if (componente.isRepresentante()) {
			for (Componente com : grupo.getComponentes()) {
				if (com.isRepresentante()) {
					Message.error("users.error.member.band.representative");
					success = false;
				}
			}
		}
		if (componente.getActividad() == null || "".equals(componente.getActividad())) {
			Message.error("users.error.member.instrument.null");
			success = false;
		}

		if (success) {
			componente.setGrupo(grupo);
			componente.setUsuario(usuario);
			componentesService.insertarModificarComponente(componente);
			Message.info("users.info.member.success");
			hideMemberPanel();
		}

	}

	/**
	 * Oculta el panel.
	 */
	public void hideMemberPanel() {
		showMemberPanel = false;
	}

	public Componente getComponente() {
		return componente;
	}

	public void setComponente(Componente componente) {
		this.componente = componente;
	}

	public List<Componente> getComponentes() {
		return componentes;
	}

	public void setComponentes(List<Componente> componentes) {
		this.componentes = componentes;
	}

	public List<Grupo> getGrupos() {
		return grupos;
	}

	public void setGrupos(List<Grupo> grupos) {
		this.grupos = grupos;
	}

	public List<Usuario> getUsuarios() {
		return usuarios;
	}

	public void setUsuarios(List<Usuario> usuarios) {
		this.usuarios = usuarios;
	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public Grupo getGrupo() {
		return grupo;
	}

	public void setGrupo(Grupo grupo) {
		this.grupo = grupo;
	}

	public boolean isShowMemberPanel() {
		return showMemberPanel;
	}

	public void setShowMemberPanel(boolean showMemberPanel) {
		this.showMemberPanel = showMemberPanel;
	}

	public void setComponentesSeleccionados(List<Componente> componentesSeleccionados) {
		this.componentesSeleccionados = componentesSeleccionados;
	}

	public List<Componente> getComponentesSeleccionados() {
		return componentesSeleccionados;
	}

	public void setSelected(Map<Componente, Boolean> selected) {
		this.selected = selected;
	}

	public Map<Componente, Boolean> getSelected() {
		return selected;
	}

	public boolean isVerComponentes() {
		return verComponentes;
	}

	public void setVerComponentes(boolean verComponentes) {
		this.verComponentes = verComponentes;
	}

	public boolean isAsignarComponentes() {
		return asignarComponentes;
	}

	public void setAsignarComponentes(boolean asignarComponentes) {
		this.asignarComponentes = asignarComponentes;
	}

}
